<?php

require_once('db.php');
require_once('config.php');


class AddressSelector
{
    function __construct()
    {
        /* PDO */
        $db_server = trim($db_server);
        $db_username = trim($db_username);
        $db_password = trim($db_password);
        $db_database = trim($db_database);
        $this->db = new db("mysql:host=$db_server;dbname=$db_database", $db_username, $db_password);
    }


    function getRegions()
    {
        $sql = "
        SELECT
            left(code, 2) AS code,
            concat(name, ' ', socr) as title,
            left(name, 1) AS letter,
            indeks,
            name,
            socr,
            gninmb,
            ocatd
            FROM kladr k
            WHERE
                code like '__00000000000'
            ORDER BY title";

        $rows = $this->db->run($sql);

        $this->filterFirstLetters($rows);

        return $rows;
    }


    function renderJSON($data)
    {
        $html = '';
        $comma = '';

        foreach($data as $row)
        {
            if (empty($row['name']))
                $row['name'] = '(без района)';
            $html .= $comma . $this->makeCode($row);
            $comma = ',';
        }

        $html = "[".$html."]";

        return $html;
    }


    function getCities($region_code)
    {
        // Города
        // СС РРР ГГГ ППП АА
        $code = substr($region_code, 0, 2);
        $sql = "
        SELECT
            left(code, 8) as code,
            left(name, 1) AS letter,
            name as title,
            name,
            indeks,
            socr,
            gninmb,
            ocatd
            FROM kladr k
            WHERE code like '".$code."000___00000'
                AND NOT (code = '".$code."00000000000' AND socr<>'г')
        ORDER BY title";

        $rows = $this->db->run($sql);

        $this->filterFirstLetters($rows);

        return $rows;
    }


    // first letters. clear not first word
    function filterFirstLetters(&$rows)
    {
        $pre_letter = '';

        foreach($rows as &$row)
        {
            if ($pre_letter == $row['letter'])
                $row['letter'] = '';
            else
                $pre_letter = $row['letter'];
        }
    }


    function renderCities($cities, $region)
    {
        global $baseurl;
        $count = count($cities);

        ob_start();
        ?>
        <div class="cities">
            <div class="column">
                <a class="back" href="/regions.js<?= $this->makeCode(2, $region) ?>">&larr; Назад</a>
                <br>
                <?php foreach($cities as $city): ?>
                    <a href="<?= $this->makeCode(4, $city) ?>"><?= $city['title'] ?></a>
                <?php endforeach; ?>
                <a class="more" href="/regions/<?= $region['code'] ?>.js<?= $this->makeCode(2, $region) ?>">Другие...</a>
            </div>
            <br clear="all">
        </div>
        <?php

        $html = ob_get_contents();
        ob_end_clean();

        return $html;
    }


    function renderPage($json)
    {
        $html = '';
        $html .= "AddressSelectorShow({$json})";

//        $html = self::sanitizeOutput($html);

        return $html;
    }


    function getSubRegions($region_code)
    {
        // Районы
        // СС РРР ГГГ ППП АА
        $code = substr($region_code, 0, 2);
        $sql = "
        SELECT
            left(code, 8) as code,
            concat(name,' ',socr) as title,
            indeks,
            name,
            socr,
            gninmb,
            ocatd
            FROM kladr k
            WHERE code like '".$code."___00000000'
                /*AND code <> '".$code."000___00000'*/
                AND code <> '".$code."00000000000'
        UNION
        SELECT
            left(code, 8) as code,
            '(без района)' as title,
            '' as indeks,
            '' as name,
            '' as socr,
            '' as gninmb,
            '' as ocatd
            FROM kladr k
            WHERE code = '".$code."00000000000'
        ORDER BY title";

        $rows = $this->db->run($sql);

        return $rows;
    }


    function getAllCities($region_code)
    {
        // Населенные пункты
        // СС РРР ГГГ ППП АА
        // СС
        $code = substr($region_code, 0, 8);
        $code2 = substr($code, 0, 2);
        // РРР
        if (substr($code, 5, 3) == '000')
        {
            $code5 = substr($code, 0, 5);
            $like_expr = "code like '".$code5."______00'";
        }
        // ГГГ
        else
        {
            $code8 = substr($code, 0, 8);
            $like_expr = "code like '".$code8."___00'";
        }
        // Включая тер
        // Включая снт
        $add_ter = false ? "" : "AND socr <> 'тер'";
        $add_snt = false ? "" : "AND socr <> 'снт'";
        $sql = "
        SELECT
            left(code, 11) as code,
            concat(name, ' (', socr, ')') as title,
            indeks,
            name,
            gninmb,
            socr,
            ocatd
            FROM kladr k
            WHERE
                $like_expr
                $add_ter
                $add_snt
                AND code <> '".$code2."00000000000'
                AND code <> '".$code2."000___00000'
                AND code <> '".$code."00000'
        ORDER BY title";

        $rows = $this->db->run($sql);

        return $rows;
    }


    function renderAllCities($cities, $region)
    {
        global $baseurl;
        $count = count($cities);

        ob_start();
        ?>
        <div class="cities">
            <div class="column">
                <a class="back" href="/regions/<?= $region['code'] ?>.js<?= $this->makeCode(3, $region) ?>">&larr; Назад</a>
                <br>
                <?php foreach($cities as $city): ?>
                    <a href="<?= $this->makeCode(4, $city) ?>"><?= $city['title'] ?></a>
                <?php endforeach; ?>
            </div>
        </div>
        <?php

        $html = ob_get_contents();
        ob_end_clean();

        return $html;
    }


    function renderAllCitiesOne($cities, $region)
    {
        global $baseurl;
        $count = count($cities);

        ob_start();
        ?>
        <div class="cities">
            <div class="column">
                <a class="back" href="/cities/<?= $region['code'] ?>.js<?= $this->makeCode(3, $region) ?>">&larr; Назад</a>
                <br>
                <?php foreach($cities as $city): ?>
                    <a href="<?= $this->makeCode(4, $city) ?>"><?= $city['title'] ?></a>
                <?php endforeach; ?>
            </div>
        </div>
        <?php

        $html = ob_get_contents();
        ob_end_clean();

        return $html;
    }


    function renderSubregions($subregions, $region)
    {
        global $baseurl;
        $count = count($subregions);

        ob_start();
        ?>
        <div class="subregions">
            <div class="column">
                <a class="back" href="/cities/<?= $region['code'] ?>.js<?= $this->makeCode(2, $region) ?>">&larr; Назад</a>
                <br>
                <?php foreach($subregions as $subregion): ?>
                    <a href="/cities-all/<?= $subregion['code'] ?>.js<?= $this->makeCode(3, $subregion) ?>"><?= $subregion['title'] ?></a>
                <?php endforeach; ?>
            </div>
        </div>
        <?php

        $html = ob_get_contents();
        ob_end_clean();

        return $html;
    }


    function makeCode($row)
    {
        // [code, name, socr, index, gninmb, ocatd]
        $code = "[\"$row[level]\",\"$row[code]\",\"$row[name]\",\"$row[socr]\",\"$row[indeks]\",\"$row[gninmb]\",\"$row[ocatd]\"]";

        return $code;
    }


    function sanitizeOutput($buffer)
    {
        $search = array(
            '/\>[^\S ]+/s', //strip whitespaces after tags, except space
            '/[^\S ]+\</s', //strip whitespaces before tags, except space
            '/(\s)+/s'  // shorten multiple whitespace sequences
            );
        $replace = array(
            '>',
            '<',
            '\\1'
            );
      $buffer = preg_replace($search, $replace, $buffer);
        return $buffer;
    }


    function setLevel($rows, $level)
    {
        foreach($rows as &$row)
            $row['level'] = $level;

        return $rows;
    }
}


// folders
@mkdir('.'.$baseurl);
@mkdir('.'.$baseurl.'/cities');
@mkdir('.'.$baseurl.'/regions');
@mkdir('.'.$baseurl.'/cities-all');

// files
@copy('index.html', '.'.$baseurl.'/index.html');
@copy('style.css', '.'.$baseurl.'/style.css');

$a = new AddressSelector();
$splitter = array(
    'level' => '',
    'code' => '',
    'letter' => '',
    'title' => '',
    'name' => '',
    'indeks' => '',
    'socr' => '',
    'gninmb' => '',
    'ocatd' => '',
    );

// regions
$regions = $a->getRegions();
$regions = $a->setLevel($regions, 2);
$json = $a->renderJSON($regions);
$html = $a->renderPage($json);
file_put_contents('.'.$baseurl.'/regions.js', $html);

// cities
foreach($regions as $region)
{
    $items = array();
    $cities = $a->getCities($region['code']);
    $cities = $a->setLevel($cities, 4);
    $subregions = $a->getSubRegions($region['code']);
    $subregions = $a->setLevel($subregions, 3);

    if (!empty($cities))
    {
        foreach($cities as $item)
            array_push($items, $item);
        array_push($items, $splitter);
    }
    // no subregions (Moscow, Spb)
    if (count($subregions) == 1)
    {
        print_r($region);
        //$allcities = $a->getAllCities($region['code']);
        //$allcities = $a->setLevel($cities, 4);
        //$json = $a->renderJSON($cities);
        //$html = $a->renderPage($json);
        //file_put_contents('.'.$baseurl.'/regions/'.$region['code'].'.js', $html);
        //array_push($items, $region);
        //array_push($items, $splitter);
        //foreach($allcities as $item)
        //    array_push($items, $item);
        //array_push($items, $splitter);
    }
    if (!empty($subregions))
    {
        foreach($subregions as $item)
            array_push($items, $item);
    }
    $json = $a->renderJSON($items);
    $html = $a->renderPage($json);
    file_put_contents('.'.$baseurl.'/regions/'.$region['code'].'.js', $html);

    // regions cities
    // all cities (by subregions)
    foreach($subregions as $subregion)
    {
        $cities = $a->getAllCities($subregion['code']);
        $cities = $a->setLevel($cities, 4);
        $json = $a->renderJSON($cities);
        $html = $a->renderPage($json);
        file_put_contents('.'.$baseurl.'/cities-all/'.$subregion['code'].'.js', $html);
    }
}
